//erik wright
//bot_motion.h

/*
this headder file describes the class structure of a LLL.  The goal
of this collection of classes is to make different motions of an 
animatronic marionette.  This library is intended to be used in a 
shell environment where a genetic algorithm will define how the 
marionette moves.  The functionality of that genetic algorithm will 
be defined in the shell environment that uses this headder file.
*/


/*
motion_event
This class describes a linear linked list structure of motor control
events.  Each event consists of:
		<ch>	Channel Number in decimal, 0-31
		<pw>	Pulse width in microseconds, 500 to 2500
		<spd>	Movement speed in uS per second for one channel (optional)
		<time>	Time in mS for the entire move, affects all channels, 65535 MAX
		<cr>	Carriage return character, ASCII 13. (Required to initiate action)
		<esc>	Cancel the current command, ASCII 27. 

	(Data sheet: "Lynxmotion SSC-32 (Ver 2.0)", pg. 5)
Serial Data Format
	Servo Move:	#<ch> P<pw> S<spd>
	Group Move:	#<ch> #<ch> P<pw> S<spd> T<time><cr>

Note:  This controller is designed for angled servos.  For this project, continuous 
rotation servos have been chosen to lift the limbs of the robot, and only angled 
servos have been chosen for the inner body.
	Angled Servo:	pulse_width = 1500 is dead center, each uSec corresponds to some
			amount of angle.
	Continuous Rot:	pulse_width = 1500 is no rotation, each uSec of PWM correponds to
			some RPM.
*/

class motion_event
{
	private:
	//data
	motion_event* next;		//pointer to the next element	
	int pulse_width;		//pulse width in uSEC, 500 to 2500
	int rot_time;			//amount of time to reach specified Pulse Width value
	int ramp_speed;			//uSec per Second of PWM ramping

	//functions
	void display_event();			//formats and displays the event to standard out
	void recursive_delete(motion_event*); 			//recursive function to delete list
	void insert_at_end_recur(motion_event*, motion_event *&);	//recursively inserts at end
	void recursive_inorder_display(motion_event* );
	void recur_deep_cpy(motion_event*&, motion_event*);	//recursively perform deep copy
	int lengthof(motion_event*);		//finds the lenght of the list
	motion_event* goto_event(motion_event*, int);
	motion_event* remove_from_swappoint(motion_event*&, int);
	void recur_avg(motion_event*& , motion_event*&, motion_event*& ); 

	public:
	~motion_event();				//class deconstructor
	motion_event();					//class constructor
	motion_event(int pw_val, int rmp_spd, int event_time);			//loaded constructor
	motion_event(const motion_event&);			//class copy constructor
	void insert_at_end(motion_event *&);	//insert a node, or many, at the end of given list
	void inorder_display();		//recursively displays event and subsequent events in list
	void binary_twist(motion_event*&, bool);
	void binary_twist_rand(motion_event*&, bool);		//randomly chooses a swap point	
	void average_twist(motion_event*&);
	void weighted_average_twist(motion_event*&, int);

};
